package cn.net.dpi.shp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.net.dpi.shp.model.entity.HdLinkBoundary;
import cn.net.dpi.shp.mapper.HdLinkBoundaryMapper;
import cn.net.dpi.shp.service.HdLinkBoundaryService;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.springframework.beans.factory.annotation.Autowired;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.springframework.stereotype.Service;
import cn.net.dpi.shp.service.ShapefileService;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 道路边界服务实现类
 *
 * @author ake
 * @since 2024-12-27
 */
@Service
@Slf4j
public class HdLinkBoundaryServiceImpl extends ServiceImpl<HdLinkBoundaryMapper, HdLinkBoundary> implements HdLinkBoundaryService, ShapefileService {

    private static final String ENTITY_BASE_NAME = HdLinkBoundary.class.getAnnotation(TableName.class).value();

    /**
      * 检查并清理当前shp文件，已经存在先删除
      *
      * @param fileId
      */
    @DS("#area")
    private void checkAndClearRecords(Long fileId, String area) {
        /**
         * 检查下是否已经存在，已经存在先删除
         */
        LambdaQueryWrapper<HdLinkBoundary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HdLinkBoundary::getFileId, fileId);
        if (this.exists(queryWrapper)) {
            if (this.remove(queryWrapper)) {
                log.warn("HdLinkBoundary fileId:{} already exists, delete success and prerare parse again.", fileId);
            } else {
                log.warn("HdLinkBoundary fileId:{} already exists, delete failed and do not parse, maybe check.", fileId);
            }
        }
    }

    private List<HdLinkBoundary> parseShpfile(Long fileId, String filePath, String version,Integer versionFlag) {
        List<Map> mapList = defaultParseShpfile(filePath);
        if (mapList.isEmpty()){
            return Collections.EMPTY_LIST;
        }
        List<HdLinkBoundary> collect = mapList.stream().map(m -> {
            HdLinkBoundary obj = BeanUtil.copyProperties(m, HdLinkBoundary.class, SHP_DEFAULT_GEM_NAME);
            Object o = m.get(SHP_DEFAULT_GEM_NAME);
            if (o instanceof MultiLineString) {
                MultiLineString theGeom = (MultiLineString) o;
                LineString geometry = (LineString) theGeom.getGeometryN(0);
                obj.setGeometry(geometry);
            } else if (o instanceof LineString) {
                obj.setGeometry((LineString) o);
            } else {
                log.warn("geometry definition type:{} error:{}", LineString.class, o.getClass());
            }
            obj.setFileId(fileId);
            obj.setVersion(version);
            obj.setVersionFlag(versionFlag);
        return obj;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    @DS("#area")
    public boolean parseShpfile(Long fileId, String baseName, String filePath, String version,Integer versionFlag, String area) {
        if (StringUtils.equalsIgnoreCase(baseName, ENTITY_BASE_NAME)) {

            checkAndClearRecords(fileId, area);

            List<HdLinkBoundary> collect = parseShpfile(fileId, filePath, version, versionFlag);

            if (!CollectionUtils.isEmpty(collect)) {
                if (this.saveBatch(collect)) {
                    log.warn("HdLinkBoundary saveBatch success,size:{}", collect.size());
                    return true;
                } else {
                    log.warn("HdLinkBoundary saveBatch failed,size:{}", collect.size());
                }
            } else {
                log.warn("HdLinkBoundary file:{},has no result", filePath);
            }
        }
        return false;
    }
}
